package com.butnet.sqltools.connection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class DBTools {
	private Map<String, Connection> maps = new LinkedHashMap<String, Connection>();
	private Map<String, Config> confs = new LinkedHashMap<String, Config>();
	private Map<String, List<String>> history = new LinkedHashMap<String, List<String>>();
	private Exception lastError = null;
	private int maxHistoryCount = 10;
	
	public int getMaxHistoryCount() {
		return maxHistoryCount;
	}
	public void setMaxHistoryCount(int maxHistoryCount) {
		if(maxHistoryCount<=0)maxHistoryCount=10;
		this.maxHistoryCount = maxHistoryCount;
	}
	
	public Connection get(String name) {
		return maps.get(name);
	}
	
	public Config getConfig(String name){
		return confs.get(name);
	}
	
	public Exception getLastError() {
		return lastError;
	}

	public Connection build(Config conf) {
		Connection conn = null;
		try {
			String driveClsName = conf.get("ClassString");
			String url = conf.get("ConnectionString");
			String user = conf.get("UserName"), pwd = conf.get("PassWord");
			
			System.out.println(driveClsName);
			Class.forName(driveClsName);
			
			if ((user == null) && (pwd == null)) {
				conn = DriverManager.getConnection(url);
			} else {
				conn = DriverManager.getConnection(url, user, pwd);
			}
		} catch (Exception e) {
			e.printStackTrace(System.err);
			lastError = e;
			return null;
		}
		maps.put(conf.getName(), conn);
		confs.put(conf.getName(), conf);
		return conn;
	}

	public Iterator<Entry<String, Connection>> getHeader() {
		return maps.entrySet().iterator();
	}

	public boolean closeAll() {
		try {
			for (Iterator<Entry<String, Connection>> it = getHeader(); it.hasNext();) {
				Connection con = it.next().getValue();
				if (!con.isClosed())
					con.close();
			}
		} catch (Exception e) {
			e.printStackTrace(System.err);
			return false;
		}
		return true;
	}

	public boolean close(String name) {
		Connection con = maps.get(name);
		try {
			if (con != null && !con.isClosed())
				con.close();
		} catch (Exception e) {
			e.printStackTrace(System.err);
			return false;
		}
		return true;
	}
	
	public void remove(String name){
		if(close(name))
			maps.remove(name);
	}

	public ExecOver executeQuery(String name, String sql) throws SQLException {
		Connection con = get(name);
		if(con==null)
			return null;
		PreparedStatement ps = null;
		ps = con.prepareStatement(sql);
		ExecOver over = new ExecOver();
		over.res = ps.execute();
		over.ps = ps;
		
		List<String> h = null;
		if(history.containsKey(name))
			h = history.get(name);
		else{
			h = new LinkedList<String>();
			history.put(name, h);
		}
		if(!h.contains(sql)){
			h.add(0, sql);
			
			while(h.size()>maxHistoryCount){
				h.remove(h.size()-1);
			}
		}
		return over;
	}
	public Map<String, List<String>> getHistory() {
		return history;
	}
	public List<String> getHistory(String name){
		return history.get(name);
	}
	public class ExecOver{
		public PreparedStatement ps = null;
		public boolean res;
	}
}
